1 module d_getter; 2 import commons; 3 4 enum DmdVersion = "2.105.0"; 5 enum LdcVersion = "1.36.0-beta1"; 6 7 private string getDmdLink() 8 { 9 import std.system; 10 string link = "https://downloads.dlang.org/releases/2.x/" ~ DmdVersion ~ "/dmd." ~ DmdVersion; 11 return link ~ (os == OS.linux ? ".linux.tar.xz" : os == OS.osx ? ".osx.tar.xz" : ".windows.7z"); 12 } 13 private string getDmdDownloadOutputName() 14 { 15 version(Posix) return "dmd-"~DmdVersion~".tar.xz"; 16 else return "dmd-"~DmdVersion~".7z"; 17 } 18 19 20 private string getLdcLink() 21 { 22 string baseDownloadLink = "https://github.com/ldc-developers/ldc/releases/download/"; 23 baseDownloadLink~= "v"~LdcVersion; 24 baseDownloadLink~= "/ldc2-"~LdcVersion~"-"; 25 version(Windows) 26 baseDownloadLink~= "windows-x64.7z"; 27 else version(OSX) 28 baseDownloadLink~= "osx-universal.tar.xz"; 29 else version(linux) 30 baseDownloadLink~= "linux-x86_64.tar.xz"; 31 else assert(false, "D is not supported in your system."); 32 return baseDownloadLink; 33 } 34 35 private string getOutputPath() 36 { 37 string outputPath = buildNormalizedPath(std.file.getcwd(), "D"); 38 string fileName = "ldc2-"~LdcVersion~"-"; 39 version(Windows) fileName~= "windows-x64"; 40 else version(linux) fileName~= "linux-x86_64"; 41 else version(OSX) fileName~= "osx-universal"; 42 else assert(false, "Not implemented for your system."); 43 return buildNormalizedPath(outputPath, fileName); 44 } 45 private string getDmdOutputPath() 46 { 47 string outputPath = buildNormalizedPath(std.file.getcwd(), "D"); 48 string fileName = "dmd-"~DmdVersion~"-"; 49 version(Windows) fileName~= "windows-x64"; 50 else version(linux) fileName~= "linux-x86_64"; 51 else version(OSX) fileName~= "osx-universal"; 52 else assert(false, "Not implemented for your system."); 53 return buildNormalizedPath(outputPath, fileName); 54 } 55 56 private string getLdcDownloadOutputName() 57 { 58 static string fileName; 59 if(!fileName) 60 { 61 fileName = "ldc2-"~LdcVersion~"-"; 62 version(Windows) fileName~= "windows-x64.7z"; 63 else version(linux) fileName~= "linux-x86_64.tar.xz"; 64 else version(OSX) fileName~= "osx-universal.tar.xz"; 65 else assert(false, "System not supported."); 66 } 67 return fileName; 68 } 69 70 71 /** 72 * Must check if ~/.ldc2.conf (%APPDATA%\.ldc\ldc2.conf) exists and then ignore it. 73 * This is a fix since Hipreme Engine should contain the entire build command and make it 74 * predictable. 75 * Here, it uses the 2nd ldc2.conf, so, one is still able to tweak although not recommended 76 * https://wiki.dlang.org/Using_LDC - Next to ldc2 executable. 77 */ 78 private void overrideLdcConf(ref Terminal t) 79 { 80 static import std.file; 81 string ldc2Conf = buildNormalizedPath(getOutputPath(), "etc", "ldc2.conf"); 82 t.writelnHighlighted("Overriding ldc2.conf to use one next to ldc executable."); 83 std.file.copy(ldc2Conf, buildNormalizedPath(getOutputPath(), "bin", "ldc2.conf")); 84 } 85 86 enum wontAffectMessage = "\n\tThis compiler version is installed locally and won't affect your system D installation."; 87 88 bool installD(ref Terminal t, ref RealTimeConsoleInput input) 89 { 90 bool existsDmd = ("dmdPath" in configs) !is null; 91 bool existsLdc = ("ldcPath" in configs) !is null; 92 bool isDmdExpectedVersion = existsDmd && configs["dmdVersion"].str == DmdVersion; 93 bool isLdcExpectedVersion = existsLdc && configs["ldcVersion"].str == LdcVersion; 94 95 if(!isLdcExpectedVersion) 96 { 97 if(!existsLdc) 98 t.writelnHighlighted("No ldcVersion specified, your HipremeEngine will attempt to install locally LDC2 " ~LdcVersion ~ 99 wontAffectMessage); 100 else 101 t.writelnError("Different LDC Version. HipremeEngine will attempt to install locally LDC2 " ~LdcVersion); 102 t.flush; 103 if(!installFileTo("Download D cross compiler LDC2 "~LdcVersion, getLdcLink, 104 getLdcDownloadOutputName, buildNormalizedPath(std.file.getcwd, "D"), t, input)) 105 { 106 t.writelnError("Install failed"); 107 return false; 108 } 109 t.writeln("Installed."); 110 auto binPath = buildNormalizedPath(getOutputPath, "bin"); 111 makeFileExecutable(buildNormalizedPath(binPath, "rdmd")); 112 makeFileExecutable(buildNormalizedPath(binPath, "ldc2")); 113 makeFileExecutable(buildNormalizedPath(binPath, "ldmd2")); 114 makeFileExecutable(buildNormalizedPath(binPath, "dub")); 115 overrideLdcConf(t); 116 117 string rdmd = buildNormalizedPath(binPath, "rdmd"); 118 version(Windows) rdmd = rdmd.setExtension("exe"); 119 configs["ldcVersion"] = LdcVersion; 120 configs["ldcPath"] = getOutputPath; 121 configs["rdmdPath"] = rdmd; 122 configs["dubPath"] = binPath; 123 updateConfigFile(); 124 } 125 if(!isDmdExpectedVersion) 126 { 127 if(!existsDmd) 128 t.writelnHighlighted("No dmdVersion specified, your HipremeEngine will attempt to install locally DMD " ~DmdVersion ~ 129 wontAffectMessage); 130 else 131 t.writelnError("Different DMD Version. HipremeEngine will attempt to install locally DMD " ~DmdVersion); 132 t.flush; 133 if(!installFileTo("Download D fast iteration compiler DMD "~DmdVersion, getDmdLink, 134 getDmdDownloadOutputName, buildNormalizedPath(std.file.getcwd, "D"), t, input)) 135 { 136 t.writelnError("Install failed"); 137 t.flush; 138 return false; 139 } 140 import std.system; 141 142 string sys; 143 string bin = "bin"; 144 switch(os) with(OS) 145 { 146 case osx: sys = "osx"; break; 147 case win32, win64: sys = "windows"; break; 148 case linux: sys = "linux"; bin = "bin64"; break; 149 default: assert(false, "System not supported."); 150 } 151 string binPath = buildNormalizedPath(getDmdOutputPath, "dmd2", sys, bin); 152 makeFileExecutable(buildNormalizedPath(binPath, "dmd")); 153 makeFileExecutable(buildNormalizedPath(binPath, "dub")); 154 makeFileExecutable(buildNormalizedPath(binPath, "rdmd")); 155 156 configs["dmdVersion"] = DmdVersion; 157 configs["dmdPath"] = binPath; 158 updateConfigFile(); 159 } 160 161 return true; 162 } 163 164 165 bool setupD(ref Terminal t, ref RealTimeConsoleInput input) 166 { 167 if(!installD(t, input)) 168 { 169 t.writelnError("Could not setup D. Aborting process"); 170 return false; 171 } 172 string concatPath = ":"; 173 version(Windows) concatPath = ";"; 174 175 import std.array:join; 176 environment["PATH"] = join([ 177 configs["dmdPath"].str, 178 buildNormalizedPath(configs["ldcPath"].str, "bin"), 179 environment["PATH"] 180 ], concatPath); 181 182 return true; 183 }